package com.deanlib.cabinet.ui.view.photo;

import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.GridLayoutManager;

import com.deanlib.cabinet.R;
import com.deanlib.cabinet.base.BaseFragment;
import com.deanlib.cabinet.data.AppDatabase;
import com.deanlib.cabinet.data.db.ResourceDao;
import com.deanlib.cabinet.data.event.ResourceChangeEvent;
import com.deanlib.cabinet.data.event.ResourceSyncEvent;
import com.deanlib.cabinet.data.model.Resource;
import com.deanlib.cabinet.data.model.User;
import com.deanlib.cabinet.data.network.schedulers.SchedulerProvider;
import com.deanlib.cabinet.databinding.FragmentPhotoListBinding;
import com.deanlib.cabinet.ui.adapter.MediaGridAdapter;
import com.deanlib.cabinet.utils.ConfigManager;
import com.deanlib.cabinet.utils.DataUtils;
import com.deanlib.cabinet.utils.UserManager;
import com.scwang.smart.refresh.layout.api.RefreshLayout;
import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.greenrobot.greendao.query.QueryBuilder;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import io.reactivex.Observable;
import io.reactivex.ObservableOnSubscribe;

/**
 * 登录用户展示页面
 * Created by Dean on 2022/6/28
 */
public class PhotoListFragment extends BaseFragment<FragmentPhotoListBinding> {

    private GridLayoutManager mGridLayoutManager;
    MediaGridAdapter mediaGridAdapter;
    List<MediaGridAdapter.MediaGridData> mediaGridDataList;
    int pageSize = 30;
    int pageNum = 1;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EventBus.getDefault().register(this);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }

    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    public void eventResourceSync(ResourceSyncEvent event) {
        if (!TextUtils.isEmpty(event.resource.path)) {
            //上传成功
            if (mediaGridAdapter != null && mediaGridDataList != null) {
                for (int i = 0; i < mediaGridDataList.size(); i++) {
                    Resource resource = mediaGridDataList.get(i).getData();
                    if (resource != null && resource.md5.equals(event.md5)) {
                        resource.path = event.resource.path;
                        mediaGridAdapter.notifyItemChanged(i);
                        break;
                    }
                }
            }
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    public void eventResourceChange(ResourceChangeEvent event) {
        reloadDBData();
    }

    @Override
    public void initView() {
        mGridLayoutManager = new GridLayoutManager(getContext(), 3);

        mGridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                if (mediaGridDataList.get(position).getType() == MediaGridAdapter.VIEW_TYPE_ITEM_TIME) {
                    return mGridLayoutManager.getSpanCount();
                } else {
                    return 1;
                }
            }
        });
        /**
         * 当标题栏被悬浮的时候的点击功能
         */
//        binding.prvResource.setOnPinnedHeaderClickListener(new PinnedHeaderRecyclerView.OnPinnedHeaderClickListener() {
//            @Override
//            public void onPinnedHeaderClick(int adapterPosition) {
////                mediaGridAdapter.switchExpand(adapterPosition);
//                //标题栏被点击之后，滑动到指定位置
//                mGridLayoutManager.scrollToPositionWithOffset(adapterPosition, 0);
//            }
//        });

        binding.prvResource.setLayoutManager(mGridLayoutManager);
        mediaGridAdapter = new MediaGridAdapter(mediaGridDataList = new ArrayList<>());
        binding.prvResource.setAdapter(mediaGridAdapter);
//        binding.prvResource.addItemDecoration(new PinnedHeaderItemDecoration(getContext()));

        binding.srLayout.setOnRefreshLoadMoreListener(new OnRefreshLoadMoreListener() {
            @Override
            public void onLoadMore(@NonNull RefreshLayout refreshLayout) {
                pageNum++;
                loadMore();
            }

            @Override
            public void onRefresh(@NonNull RefreshLayout refreshLayout) {
                pageNum = 1;
                mediaGridDataList.clear();
                loadMore();
            }
        });
    }

    /**
     * 翻页用
     */
    private void loadMore() {
        int offset = (pageNum - 1) * pageSize;
        if (offset < 0) offset = 0;
        loadDBData(offset, pageSize);
    }

    @Override
    public void loadData() {
        //先加载本地数据库数据
        loadMore();
    }

    @Override
    public int getLayoutId() {
        return R.layout.fragment_photo_list;
    }

    /**
     * 把数据都存在本地数据库中
     * 然后通过该方法查询出数据并展示
     */
    private void loadDBData(int offset, int limit) {
        addDisposable(Observable.create((ObservableOnSubscribe<List<MediaGridAdapter.MediaGridData>>) emitter -> {
            //查询数据库数据
//            dbResourceList = AppDatabase.getDaoSession().queryBuilder(Resource.class)
//                    .orderDesc(ResourceDao.Properties.ResCreateTime)
//                    .offset(offset).limit(limit).list();
            QueryBuilder<Resource> resourceQueryBuilder = AppDatabase.getDaoSession().getResourceDao().queryBuilder();

            List<Long> sharedUserList = new ArrayList<>();

            if (ConfigManager.getInstance().enableShared()
                    && UserManager.getInstance().getSharedUserMap() != null
                    && UserManager.getInstance().getSharedUserMap().size() > 0) {
                //如果有关联关系
                sharedUserList.add(UserManager.getInstance().getLogin().user.id);
                for (Map.Entry<Long, User> item : UserManager.getInstance().getSharedUserMap().entrySet()) {
                    sharedUserList.add(item.getKey());
                }
                //先查关系，再查资源
                //需要用到联合查询
//                resourceQueryBuilder.join(ResourceDao.Properties.Id, UserResource.class, UserResourceDao.Properties.ResourceId)
//                        .where(UserResourceDao.Properties.UserId.in(sharedUserList));
            }else {
                //优化了查询
//                resourceQueryBuilder.where(ResourceDao.Properties.IsCreator.eq(true));
            }

            List<Resource> dbResourceList = resourceQueryBuilder.orderDesc(ResourceDao.Properties.ResCreateTime)
                    .offset(offset).limit(limit).list();
            if (dbResourceList != null) {
//            Collections.sort(dbResourceList);//时间排序 //IllegalArgumentException: Comparison method violates its general contract!
                emitter.onNext(DataUtils.createMediaGridData(dbResourceList));
            }
            emitter.onComplete();
        }).compose(SchedulerProvider.getInstance().applySchedulers()).subscribe(data -> {
            binding.loading.setVisibility(View.GONE);
            if (binding.srLayout.isRefreshing()) {
                binding.srLayout.finishRefresh();
            } else if (binding.srLayout.isLoading()) {
                if (data.isEmpty()) {
                    binding.srLayout.finishLoadMoreWithNoMoreData();
                    return;
                } else {
                    binding.srLayout.finishLoadMore();
                }
            }
            int position = mediaGridDataList.size();
            mediaGridDataList.addAll(data);
            mediaGridAdapter.notifyItemRangeChanged(position, data.size());
        }));
    }

    /**
     * 用于重新加载数据库数据
     */
    private void reloadDBData() {
        int limit = mediaGridDataList.size();
        if (limit <= 0) {
            limit = pageSize;
        }
        mediaGridDataList.clear();
        loadDBData(0, limit);
    }

}
